/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is Forte for Java, Community Edition. The Initial * Developer of the Original Code is Sun Microsystems, Inc. Portions * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. */ package org.netbeans.modules.apisupport; import java.io.*; import java.lang.reflect.InvocationTargetException; import java.util.*; import java.util.jar.*; import javax.swing.event.*; import org.openide.execution.Executor; import org.openide.modules.*; import org.openide.loaders.*; import org.openide.nodes.*; import org.openide.util.NbBundle; import org.openide.util.Utilities; import org.openide.util.WeakListener; public interface ManifestProvider extends Node.Cookie { public Manifest getManifest () throws IOException; public void setManifest (Manifest m) throws IOException; public void addFiles (Set/* <FileObject> */ files) throws IOException; public void removeFiles (Set/* <FileObject> */ files) throws IOException; public Set/* <FileObject> */ getFiles () throws IOException; public void addChangeListener (ChangeListener list); public void removeChangeListener (ChangeListener list); public boolean isValid (); public Exception getParseException (); public File getManifestAsFile (); public static class ModuleExecSupport extends ExecSupport { public ModuleExecSupport (MultiDataObject.Entry entry) { super (entry); } protected Executor defaultExecutor () { return Executor.find (InstallModuleExecutor.class); } } public static abstract class Util extends Object { private Util () {} public static Exception checkForException (ManifestProvider p) { if (! p.isValid ()) { Exception e = p.getParseException (); if (e != null) return e; else return new Exception ("(unspecified manifest syntax error)"); } try { new ModuleDescription ("test", p.getManifest ()); return null; } catch (IOException ioe) { // Includes IllegalModuleException: return ioe; } } public static void updateName (Node n) { updateName (n, (ManifestProvider) n.getCookie (ManifestProvider.class)); } public static void updateName (final Node n, final ManifestProvider p) { try { String displayName = NbBundle.getLocalizedValue (p.getManifest ().getMainAttributes (), ModuleDescription.TAG_NAME); // [PENDING] file system annotations if (displayName == null) n.setDisplayName (n.getName () + " [no name]"); else n.setDisplayName (n.getName () + " [" + displayName + "]"); } catch (IOException ioe) { ioe.printStackTrace (); } ChangeListener list = new ChangeListener () { public void stateChanged (ChangeEvent ev) { updateName (n, p); } }; n.setValue ("ManifestProvider.Util.updateName.changeListener", list); p.addChangeListener (WeakListener.change (list, p)); } public static void addToSheet (Sheet sheet, ManifestProvider p) { Sheet.Set set = new Sheet.Set (); set.setName ("openide"); set.setDisplayName ("Module Properties"); set.setShortDescription ("General properties of the module."); set.put (new GeneralProp (p, ModuleDescription.TAG_MAGIC, "Code Name", "Code name for the module, e.g. \"com.mycom.mymodule\" or \"com.mycom.mymodule/1\".")); set.put (new GeneralProp (p, ModuleDescription.TAG_NAME, "Display Name", "Display name for this module (in the base locale only!).")); set.put (new GeneralProp (p, ModuleDescription.TAG_SPEC_VERSION, "Specification Version", "Specification version, e.g. 1.0 or 1.13.9.2.")); set.put (new GeneralProp (p, ModuleDescription.TAG_IMPL_VERSION, "Implementation Version", "Implementation version; no particular format.")); // XXX would be nicer as subnodes, but this will do for now set.put (new GeneralProp (p, ModuleDescription.TAG_MODULE_DEPENDENCIES, "Module Dependencies", "Dependencies on other modules, e.g. \"com.mycom.myothermodule/1 > 0.9.1 , org.netbeans.modules.java\".")); set.put (new GeneralProp (p, ModuleDescription.TAG_PACKAGE_DEPENDENCIES, "Package Dependencies", "Dependencies on packages and standard extensions, e.g. \"javax.servlet , javax.ejb > 1.1\".")); set.put (new GeneralProp (p, ModuleDescription.TAG_JAVA_DEPENDENCIES, "Java Dependencies", "Dependencies on Java (APIs and VM), e.g. \"Java = 1.2.1b4, VM > 1.0\".")); set.put (new GeneralProp (p, ModuleDescription.TAG_IDE_DEPENDENCIES, "IDE Dependencies", "Dependencies on the Open APIs, e.g. \"IDE/1 > 1.0\".")); sheet.put (set); set = new Sheet.Set (); set.setName ("openideparse"); set.setDisplayName ("Manifest Parsing"); set.setShortDescription ("Information pertaining to the parse status of the manifest file."); set.put (new ManifestValidProp (p)); set.put (new ManifestErrorProp (p)); sheet.put (set); } private static class GeneralProp extends PropertySupport.ReadWrite { private Attributes.Name tagname; private ManifestProvider provider; public GeneralProp (ManifestProvider provider, Attributes.Name tagname, String displayName, String shortDescription) { super (tagname.toString (), String.class, displayName, shortDescription); this.provider = provider; this.tagname = tagname; } public Object getValue () throws InvocationTargetException { try { String val = provider.getManifest ().getMainAttributes ().getValue (tagname); return (val == null) ? "" : val; } catch (IOException ioe) { throw new InvocationTargetException (ioe); } } public void setValue (Object nue) throws IllegalArgumentException, InvocationTargetException { if (! (nue instanceof String)) throw new IllegalArgumentException (); try { Manifest mani = provider.getManifest (); if (nue.equals ("")) mani.getMainAttributes ().remove (tagname); else mani.getMainAttributes ().put (tagname, nue); provider.setManifest (mani); } catch (IOException ioe) { throw new InvocationTargetException (ioe); } } public void restoreDefaultValue () throws IllegalArgumentException, InvocationTargetException { setValue (""); } public boolean supportsDefaultValue () { return true; } } private static class ManifestValidProp extends PropertySupport.ReadOnly { private ManifestProvider p; public ManifestValidProp (ManifestProvider p) { super ("manifestValid", Boolean.TYPE, "Valid Manifest", "Whether the manifest is currently valid (both in terms of raw syntax and OpenIDE requirements)."); this.p = p; } public Object getValue () { return new Boolean (checkForException (p) == null); } } private static class ManifestErrorProp extends PropertySupport.ReadOnly { private ManifestProvider p; public ManifestErrorProp (ManifestProvider p) { super ("manifestError", String.class, "Manifest Error", "Current parse error for the manifest, if any."); this.p = p; } public Object getValue () { Exception e = checkForException (p); if (e == null) return "<none>"; else if (e.getLocalizedMessage () == null) return "<unspecified " + Utilities.getShortClassName (e.getClass ()) + " error>"; else return e.getLocalizedMessage (); } } } public static class CategoryChildren extends Children.Keys { private ManifestProvider provider; private ChangeListener list; public CategoryChildren (ManifestProvider provider) { this.provider = provider; provider.addChangeListener (WeakListener.change (list = new ChangeListener () { public void stateChanged (ChangeEvent ev) { addNotify (); } }, provider)); } protected void addNotify () { setKeys (new Object[] { ModuleDescription.TAG_MAIN, ModuleDescription.TAG_DESCRIPTION, ModuleDescription.SECTION_ACTION, ModuleDescription.SECTION_CLIPBOARD_CONVERTOR, ModuleDescription.SECTION_DEBUGGER, ModuleDescription.SECTION_FILESYSTEM, ModuleDescription.SECTION_LOADER, ModuleDescription.SECTION_NODE, ModuleDescription.SECTION_OPTION, ModuleDescription.SECTION_SERVICE, /* ModuleDescription.TAG_MODULE_DEPENDENCIES, ModuleDescription.TAG_PACKAGE_DEPENDENCIES, ModuleDescription.TAG_JAVA_DEPENDENCIES, ModuleDescription.TAG_IDE_DEPENDENCIES, */ }); } protected void removeNotify () { setKeys (new Object[] { }); } protected Node[] createNodes (Object key) { return new Node[] { new CategoryNode (provider, key) }; } } } /* * Log * 5 Gandalf-post-FCS1.2.1.1 3/28/00 Jesse Glick More robust module * install executor. * 4 Gandalf-post-FCS1.2.1.0 3/23/00 Jesse Glick More informative node * names. * 3 Gandalf 1.2 1/26/00 Jesse Glick Live manifest parsing. * 2 Gandalf 1.1 1/26/00 Jesse Glick Manifest handling * changed--now more dynamic, synched properly with open document as for * real file types. * 1 Gandalf 1.0 1/22/00 Jesse Glick * $ */